#include "stdafx.h"
#include <QMessageBox>
#include <QScreen>
#include <QApplication>
#include <QDebug>
#include <QFileDialog>
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include "inputdialog.h"
#include "http_server.h"

MainWindow::MainWindow(QWidget *parent, http_service& service)
    : QMainWindow(parent)
    , ui_(new Ui::MainWindow)
    , service_(service)
    , process_(new QProcess(this))
{
    ui_->setupUi(this);
    stamp_ = new struct timeval;
    gettimeofday(stamp_, nullptr);

    connect(ui_->clear, &QPushButton::clicked, this, &MainWindow::onClear);
    connect(ui_->startServer, &QPushButton::clicked, this, &MainWindow::onStartServer);
    connect(ui_->addFile, &QPushButton::clicked, this, &MainWindow::onAddFile);
}

MainWindow::~MainWindow() {
    delete ui_;
    delete stamp_;
    delete server_;
    qDebug() << "The main windows was destroied!";
}

void MainWindow::closeEvent(QCloseEvent *event) {
    acl::fiber::schedule_stop(); // 停止协程调度器
    event->accept();  // 接受关闭事件
    return;
}

void MainWindow::onClear() {
    ui_->display->clear();
}

void MainWindow::setProgress(int n) {
    if (n == 100) {
        ui_->progress->setValue(100);
    } else {
        struct timeval now;
        gettimeofday(&now, nullptr);
        double tc = acl::stamp_sub(now, *stamp_);
        if (tc >= 200) {
            ui_->progress->setValue(n % 100);
            gettimeofday(stamp_, nullptr);
        }
    }
}

void MainWindow::onStartServer() {
    if (!acl::fiber::scheduled()) {
        qDebug() << "gui fiber not scheduled yet!";
        return;
    }

    if (server_ != nullptr) {
        qDebug() << "Fiber server is running!";
        return;
    }

    ui_->startServer->setEnabled(false);

    qDebug() << "Start fiber server";
    go[this] {
        server_ = new http_server(service_, "0.0.0.0", 80, this);
        server_->run();
    };
    qDebug() << "Fiber server started";
}

void MainWindow::onAddFile() {
    QString filePath = QFileDialog::getOpenFileName(this, "Open File", "", "All Files (*);;Text Files (*.txt)");
    if (filePath.isEmpty()) {
        return;
    }

    //QMessageBox::information(this, "File Selected", "You selected: " + filePath);

    acl::string buff;
    std::string fullPath = filePath.toStdString();
#if 1
    acl::string& key = buff.basename(fullPath.c_str());
#else
    std::string key("/");
    key += std::to_string(idx_);
    key += "/";
#endif
    files_[key.c_str()] = fullPath;
    idx_++;

    qDebug() << "Add file ok, key: " << key.c_str() << ", file: " << fullPath.c_str();
    showFiles();
}

const std::string *MainWindow::get_filepath(const char* path) {
    if (path == nullptr || *path == 0) {
        qDebug() << "path is null";
        return nullptr;
    }

    qDebug() << "Find file for path: " << path;
    const auto it = files_.find(path);
    if (it == files_.end()) {
    qDebug() << "Not found file for path: " << path;
        return nullptr;
    }

    qDebug() << "Ok, file found: " << it->second.c_str();
    return &it->second;
}

void MainWindow::onHttpOptions() {
    go[this] {
        qDebug() << "Sleep 5 seconds before starting http options dialog";
        acl::fiber::delay(5000);

        InputDialog dialog(this);
        QRect mainWindowGeometry = this->frameGeometry();
        QPoint mainWindowPos = this->pos();
        int x = mainWindowPos.x() + (mainWindowGeometry.width() - dialog.width()) / 2;
        int y = mainWindowPos.y() + (mainWindowGeometry.height() - dialog.height()) / 2;
        dialog.move(x, y);
        connect(&dialog, &InputDialog::dialogAccepted, this, &MainWindow::onDialogAccepted);
        qDebug() << "Start the http options dialog!";
        dialog.exec();
        qDebug() << "Http options dialog stopped!";
    };
    qDebug() << "Waiting for the results of http options";
}

void MainWindow::onDialogAccepted(const QString &text) {
    acl::string buf(text.toStdString().c_str());
    std::vector<acl::string>& lines = buf.split2("\r\n");
    for (const auto it : lines) {
        acl::string line = it.c_str();
        auto& kv = line.split_nameval(':');
        if (kv.first.empty() || kv.second.empty()) {
            continue;
        }
        kv.first.trim_space();
        kv.second.trim_left_space().trim_right_space();
    }
}

void MainWindow::showFiles() {
    acl::string buff;
    for (auto &it : files_) {
        buff += it.second.c_str();
        buff += "\r\n";
    }

    ui_->display->setText(buff.c_str());
}

void MainWindow::keyPressEvent(QKeyEvent *event) {
    if (event->modifiers() == Qt::ControlModifier) {
        if (event->key() == Qt::Key_N) {
        }
    }
}
